package cn.hl.service.impl;

import cn.hl.domain.MovieTicket;
import cn.hl.dto.MovieTicketDto;
import cn.hl.enums.GlobalExceptionCode;
import cn.hl.exception.GlobalCustomException;
import cn.hl.mapper.MovieTicketMapper;
import cn.hl.result.JSONResult;
import cn.hl.service.IMovieTicketService;
import cn.hl.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hulan
 * @since 2022-09-25
 */
@Service
public class MovieTicketServiceImpl extends ServiceImpl<MovieTicketMapper, MovieTicket> implements IMovieTicketService {

    @Autowired
    private MovieTicketMapper movieTicketMapper;

    @Override
    public JSONResult buyMovieTicketById(MovieTicketDto movieTicketDto) {
        Long userId = movieTicketDto.getUserId();
        Long movieTicketId = movieTicketDto.getMovieTicketId();
        Long count = movieTicketDto.getCount();
        MovieTicket movieTicket = movieTicketMapper.selectById(movieTicketId);
        Long stock = movieTicket.getStock();
        if (stock < count) {
            return JSONResult.error(GlobalExceptionCode.OUT_OF_STOCK);
        }
        movieTicket.setStock(stock - count);
        movieTicketMapper.updateById(movieTicket);
        movieTicketDto.setState(movieTicket.getState());
        List<MovieTicketDto> moiveId = movieTicketMapper.findMoiveTicket(userId);
        for (MovieTicketDto movie: moiveId) {
            if (movie.getMovieTicketId() == movieTicketId) {
                movieTicketDto.setCount(movie.getCount() + count);
                movieTicketMapper.updateUserMovie(movieTicketDto);
                return JSONResult.success();
            }
        }
        movieTicketMapper.addUserMovie(movieTicketDto);
        return JSONResult.success();
    }

    @Override
    public List<MovieTicket> findMovieTicketByUserId(Long id) {
        List<MovieTicketDto> moiveTicket = movieTicketMapper.findMoiveTicket(id);
        List<MovieTicket> list = new ArrayList<>();
        for (MovieTicketDto movie: moiveTicket) {
            MovieTicket movieTicket = movieTicketMapper.selectById(movie.getMovieTicketId());
            list.add(movieTicket);
        }
        return list;
    }

    @Override
    public JSONResult watchMovieById(MovieTicketDto movieTicketDto) throws Exception {
        Long movieTicketId = movieTicketDto.getMovieTicketId();
        Long userId = movieTicketDto.getUserId();
        MovieTicketDto movieTicket = movieTicketMapper.findMovieTicketById(userId,movieTicketId);
        AssertUtil.isNotNull(movieTicket,GlobalExceptionCode.NOT_HAVE_MOVIE_TICKET);
        Boolean boo = movieTicket.getState() == 0;
        AssertUtil.isFalse(boo,GlobalExceptionCode.USED);
        MovieTicket ticket = selectById(movieTicketId);
        boolean status = getTimeStatus(ticket.getEndTime());
        AssertUtil.isFalse(status,GlobalExceptionCode.OUT_TIME_MOVIE);
        movieTicket.setState(0L);
        movieTicketMapper.updateUserMovie(movieTicket);
        return JSONResult.success(ticket);
    }

    @Override
    public void sendMovieTicket(Long id) {
        Random ran = new Random();
        List<MovieTicket> movieTickets = getMovieTicketList();
        int index = ran.nextInt(movieTickets.size());
        MovieTicket movieTicket = movieTickets.get(index);
        movieTicket.setStock(movieTicket.getStock() - 1);
        updateById(movieTicket);
        MovieTicketDto movieTicketDto = new MovieTicketDto();
        movieTicketDto.setUserId(id);
        movieTicketDto.setCount(1L);
        movieTicketDto.setMovieTicketId(movieTicket.getId());
        movieTicketDto.setState(1L);
        movieTicketMapper.addUserMovie(movieTicketDto);
    }

    private List<MovieTicket> getMovieTicketList() {
        Wrapper<MovieTicket> wrapper = new EntityWrapper<>();
        wrapper.eq("state",1);
        return selectList(wrapper);
    }

    private boolean getTimeStatus(Date timeGson){
        Boolean boo = false;
        Date date = new Date();
        if (date.getTime() > timeGson.getTime()) {// 超时
            boo = true;
        }
        return boo;
    }
}
